////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef __WN_ALLOCATION_H__
#define __WN_ALLOCATION_H__

#include "WNCore/inc/WNBase.h"

#ifdef _WN_WINDOWS
    #include <malloc.h>

    #define WN_STACK_ALLOC(_size) _alloca(_size)
#elif defined _WN_LINUX
    #include <alloca.h>

    #define WN_STACK_ALLOC(_size) alloca(_size)
#endif

__WN_INLINE WN_VOID* WNMalloc(WN_SIZE_T _size);
__WN_INLINE WN_VOID* WNCalloc(WN_SIZE_T _count, WN_SIZE_T _size);
__WN_INLINE WN_VOID* WNRealloc(WN_VOID* _memory, WN_SIZE_T _newSize);
__WN_INLINE WN_VOID WNFree(WN_VOID* _memory);

typedef WN_VOID* (*WN_MALLOC_FUNCTION_T)(WN_SIZE_T);
typedef WN_VOID* (*WN_CALLOC_FUNCTION_T)(WN_SIZE_T, WN_SIZE_T);
typedef WN_VOID* (*WN_REALLOC_FUNCTION_T)(WN_VOID*, WN_SIZE_T);
typedef WN_VOID (*WN_FREE_FUNCTION_T)(WN_VOID*);

__WN_INLINE WN_VOID* WNAlignedMalloc(WN_SIZE_T _size, WN_SIZE_T _alignment);
__WN_INLINE WN_VOID* WNAlignedCalloc(WN_SIZE_T _count, WN_SIZE_T _size, WN_SIZE_T _alignment);
__WN_INLINE WN_VOID* WNAlignedRealloc(WN_VOID* _memory, WN_SIZE_T _newSize, WN_SIZE_T _alignment);
__WN_INLINE WN_VOID WNAlignedFree(WN_VOID* _memory);

typedef WN_VOID* (*WN_ALIGNED_MALLOC_FUNCTION_T)(WN_SIZE_T, WN_SIZE_T);
typedef WN_VOID* (*WN_ALIGNED_CALLOC_FUNCTION_T)(WN_SIZE_T, WN_SIZE_T, WN_SIZE_T);
typedef WN_VOID* (*WN_ALIGNED_REALLOC_FUNCTION_T)(WN_VOID*, WN_SIZE_T, WN_SIZE_T);
typedef WN_VOID (*WN_ALIGNED_FREE_FUNCTION_T)(WN_VOID*);

#ifdef _WN_CPLUSPLUS
    #define WN_NEW(_obj)                                    new _obj
    #define WN_ARRAY_NEW(_obj, _num)                        new _obj[_num]
    #define WN_PLACEMENT_NEW(_obj, _loc)                    new(_loc) _obj

    #ifdef _WN_DEBUG
        #define WN_DELETE(_obj)                             delete _obj; _obj = WN_NULL
        #define WN_ARRAY_DELETE(_obj)                       delete[] _obj; _obj = WN_NULL
    #else
        #define WN_DELETE(_obj)                             delete _obj
        #define WN_ARRAY_DELETE(_obj)                       delete[] _obj
    #endif
#endif

#include "WNMemory/inc/WNAllocation.inl"

#endif // __WN_ALLOCATION_H__